
/**************************************************************
	LMtmr_Set_Timer 				1 unit = 625us
	rdabt_timer_create		  		1 unit = 100ms
 ***************************************************************/
 
 
#include "sys_config.h"
#include "sys_types.h"
#include "sys_rda_arm.h"
#include "bt_types.h"
#include "host_config.h"
#include "host_timer.h"
#include "papi.h"
#include "hid.h"
#include "hid_wii.h"
#include "hid_main.h"
#include "hs_battery.h"
#include "hw_i2c_driver.h"
#include "hw_delay.h"
#include "lmp_scan.h"
#include "hid_core.h"
#include "tra_combined.h"
#include "lmp_utils.h"
#include "lmp_timer.h"
#include "Manager.h"
#include "lmp_link_key_db.h "
#include "patch.h"

/* for hid_config_eeprom */
#define HID_DEBUG_UART                      0x01
#define HID_DEBUG_CUSTOMER					0x02
#define HID_DEBUG_SLEEP					    0x04
#define HID_DEBUG_LOW_POWER					0x08
#define HID_DEBUG_SNIFF_3					0x10
#define HID_DEBUG_SPP						0x20

//add 
#define HID_DEBUG_LOW_POWER_DECT  0x40
#define HID_DEBUG_RSSI    0x80


// Init state machine
//#define HID_INIT_IDLE  0x00
//#define HID_INIT_SCAN  0x01
//#define HID_INIT_CONNECTING  0x02
#define HidScan  0x04


#define SIG_GPIO 21
#define CONNECT_GPIO 22

#define CODEBAR_SEND_TIME			48  // 16:10ms  24:15ms 


//#define MY_USER_KBST_TICK  16            //10ms
  

#define LED_ON  			   LED_ALWAYS_DARK//LED_ALWAYS_LIGHT
#define LED_OFF				   LED_ALWAYS_LIGHT//LED_ALWAYS_DARK



#define LED_Power              1
#define LED_Pair               0
#define WP_IIC_PIN             2
#define NOUSE				   				 3
#define LED_CHARGE       NOUSE
#define LED_CAPS			   NOUSE



//extern t_link_key_entry link_key_database[PRH_BS_CFG_SYS_MAX_STORED_LINK_KEYS];
extern u_int8   gLinkIndex;
extern u_int8   hFifoIndex;
extern u_int8   ghid_fifo[24];
extern u_int8  reportFlag;
extern t_hid_pskey  hid_config_eeprom;
extern HID   ghid;
extern u_int8 hid_led_num[4];
extern t_devicelink device_links[];
extern u_int8 gKeyFlag;
extern t_link_key_entry link_key_database[];

extern void _HID_PIN_SM(void);
extern void _HID_Send_KB(u_int8 reportID);
extern int HID_Connect(t_bdaddr device_addr);
extern int HID_Disconnect(void);

//extern void  MGR_SetSecurityMode(u_int8 mode);
extern void hid_set_multi(u_int8 index);
extern void _HID_INT_Disable(void);

extern void _HID_INT_Enable(void);
extern void HSMain_InitSleepMode(void *dummy);
extern void SYSpwr_Set_Register_Bit(u_int32 reg_addr,u_int8 bit_num,u_int8 value);
extern u_int8 isGhost(u_int8 *ptr,u_int8 len);
extern void Shutdown_Device(void *dummy);

extern t_SYS_Config g_sys_config;
extern u_int8   hidConFlag;
extern u_int8 _r2p_min_search_window;
extern u_int8 g_min_wakeup_interval;
extern u_int16     gHidHandle;
extern t_lmp_link *hid_link;
extern u_int16  hid_sniff_interval[3];


u_int8 chargeDect; 
//u_int8 MyLastKey;
//u_int8 Last_reportFlag;
u_int8 keyTimeHandle;
u_int8 MyKBStringCn;
u_int8 MyKBStringFlag;
u_int8 scanComFlag;
u_int8 testD[16];
u_int8  codebarTimer;









u_int8 const Test_BD_Addr[9*6]={
0x58,0x71,0x00,0x00,0x00,0x01,
0x58,0x71,0x00,0x00,0x00,0x02,
0x58,0x71,0x00,0x00,0x00,0x03,
0x58,0x71,0x00,0x00,0x00,0x04,
0x58,0x71,0x00,0x00,0x00,0x05,
0x58,0x71,0x00,0x00,0x00,0x06,
0x58,0x71,0x00,0x00,0x00,0x07,
0x58,0x71,0x00,0x00,0x00,0x08,
0x21,0x02,0x03,0x04,0x05,0x06};


void p_hid_close_scan(void *arg)   
{
	LMscan_Write_Scan_Enable(NO_SCANS_ENABLED);
	
	if(ghid.state == HidScan){
		HID_Set_LED(LED_Pair,LED_OFF,0x0);
		HID_Set_LED(LED_Power,LED_OFF,0);
		ghid.state = HidIdle;
	}
}

void p_hid_open_scan(void *arg)
{

	if(ghid.state != HidConnected){
		MGR_SetSecurityMode(MGR_NOSECURITY);
		HID_Set_LED(LED_Power,LED_ON,0x0);
		HID_Set_LED(LED_Pair,LED_FLASH,0x7000);
		LMscan_Write_Scan_Enable(BOTH_SCANS_ENABLED);
		ghid.state  = HidScan;
		rdabt_timer_create(600*3, p_hid_close_scan, NULL, RDABT_TIMER_ONESHOT); 

	}
}

u_int16 hCount;

// just for test
void p_send_data(t_lmp_link* p_link)
{
	u_int32 i;
	LMtmr_Reset_Timer(codebarTimer,CODEBAR_SEND_TIME);

	if(ghid.state != HidConnected)
		return;

	pMemset(ghid_fifo,0,9);
	
	
	ghid_fifo[3] = hCount++;
	_HID_Send_KB(1);
	ghid_fifo[3] = 0x00;
	_HID_Send_KB(1);
	

	if(hCount > 0x28)  // " Enter"
		hCount = 0x1e; //  "1"
	
	
	
	
}


void p_hid_kb_init(void)
{
	u_int8  tmp,i;
	u_int32 value;
	
	t_bd_addr  addr;
	
	
	
	//=====================================================
	memset(addr.bytes, 0, 6);
	
	//MyLastKey = 0;
	for(i=0;i<4;i++)
		hid_led_num[i] = NOUSE;
	
	LMconfig_LM_Change_Local_Name((u_int8 *)"Test Keyboard");   // Bluetooth Keyboard

	ghid.pinCodeStatus = HID_PINCODE_IDLE;
	

	// mask int 
	_HID_INT_Disable();
	// Register Set
	// low power
	if(hid_config_eeprom.testDebug & HID_DEBUG_LOW_POWER){
		RDA_WRITE_REG_BYTE(0X40250000+0x1a7,1);
		g_sys_config.min_sleep_interval = 0x4; 
		_r2p_min_search_window = 1;
		g_min_wakeup_interval       = 0x1;
	}
	
	
	/* Add the patch to interrupt come firstly */
	HID_WRITE_REG(0x40,0x00);

	HID_WRITE_REG_UINT32(0x14,0x300000ff); // pull up,decrease the bottom current
	HID_WRITE_REG_UINT32(0x18,0);   // pull down 
	HID_WRITE_REG_UINT32(0x10,0x30ffffff);
	HID_WRITE_REG(0x40,0x04);
	
	HID_WRITE_REG(0x6c,0x3c);		 //tremble time
	
	HID_WRITE_REG(0x74,0x9f);		//col row num
       
  HID_WRITE_REG(0x78,0x33);		 //idle time
	//HID_WRITE_REG_UINT32(0x04,~0x0);		//enable row

	HID_WRITE_REG_UINT32(0x04,0xCF004FFF);	 // for  Barcode gun

	// Set it into the digital mode
	value = HID_READ_REG_UINT32(0x20);
	value |= 0x1f<<21;
	HID_WRITE_REG_UINT32(0x20,value);

	// set led  bit17: clk_sel = fast  impact on the LED
	HID_WRITE_REG_UINT32(0x30,0x800000);  	
	
	// Increase the output power
	HW_SPI_Write_Data(0x248,0x1ff4);

				//pin code
	  //g_sys_config.feature_set[6] = 0x51;    //0x59 specified for ssp  (close SSP)
	 // g_sys_config.feature_set[7] = 0x00;   // 0x87 specified for ipad
	 
	 // SSP
	  g_sys_config.feature_set[6] = 0x59;    //0xf7 specified for ssp  (close SSP)
	  g_sys_config.feature_set[7] = 0x87;   // 0x7b specified for ipad
	  
	  // reset hid soft reset bit0
   tmp = HID_READ_REG(0x68);
   tmp &= 0xfe;
   HID_WRITE_REG(0x68,tmp);
   tmp |= 0x01;
   HID_WRITE_REG(0x68,tmp);

  
	
	
	//HID_Set_LED(LED_Pair,LED_OFF,0);
	HID_Set_LED(LED_CHARGE,LED_OFF,0);
	HID_Set_LED(LED_Power,LED_ON,0);
	HID_Set_LED(LED_Pair,LED_ON,0);
	//HID_Set_LED(LED_Pair,LED_FLASH,0x7fff);

	
	
	gLinkIndex = LMkeydb_EE_Load_Link();	
	
	
	
	
	if(gLinkIndex != 0xff){
		
		if(gKeyFlag == 0)
			MGR_SetSecurityMode(MGR_NOSECURITY);
		else
			MGR_SetSecurityMode(MGR_SERVICELEVEL);
		HID_Connect(ghid.address);
		rdabt_timer_create(80, p_hid_open_scan, NULL, RDABT_TIMER_ONESHOT);//8s
	}
	else{
		p_hid_open_scan(NULL);
		
	}
	
	HSBattery_Initialise();
	if(hid_config_eeprom.testDebug & HID_DEBUG_SLEEP)
		rdabt_timer_create(600*1, HSMain_InitSleepMode, NULL, RDABT_TIMER_ONESHOT);  // 1min

	_HID_INT_Enable();    // enable  int
	HID_WRITE_REG(0x40,0x05);
	HID_WRITE_REG(0xe8,0x0f);

	hCount = 0x1e;
	codebarTimer = LMtmr_Set_Timer(CODEBAR_SEND_TIME,p_send_data,NULL,0);

	
}


void p_hid_kb_isr(void)
{
	u_int8   i,array_index,matrix_index,flag,j,tt;
	u_int8   column_index, row_index,m,length,low,up;
	u_int8   num,status,fn=0,Flag_DIS;
	u_int8   ha[8]; 
	u_int8   Count_Flag;
	
	Flag_DIS = 0;
	//RDA_WRITE_REG(0x40240014,0x800); // disable sleep

	status = HID_READ_REG(KEYBOARD_STATUS_OFFSET);   // and clear the keyboard int


	
NOR_EXIT:
	// confirm the interrupt to be cleared.  --cliff
	while(1){
		num = HID_READ_REG(KEYBOARD_STATUS_OFFSET);
		if(!(num & 0x01))
			break;
		

	}		
}
  



void p_hid_kb_sch(void)
{
	u_int8 level;
	u_int8 rssi;
	
	
	
	if(hid_config_eeprom.testDebug & HID_DEBUG_LOW_POWER_DECT){
		level=HSBattery_Get_Status();
		if(level==LOWEST_POWER)  // 2.5v
		{
			void * dummy=NULL;
			
			HID_Set_LED(LED_Pair,LED_OFF,0);
			HID_Set_LED(LED_Power,LED_OFF,0);
			HID_Disconnect();
			HSMain_Enable_ADC_BIAS();
			rdabt_timer_create(15, Shutdown_Device, NULL, pTIMER_ONESHOT);  
		}
		else if(level == LOWER_POWER){   // 3v
			HID_Set_LED(LED_Pair,LED_FLASH,0x7fff);  
		}
	
	}
	
	
	if(RDA_READ_REG(0x40250120)&0x4000)//power off while detect charging
	{
		HSMain_Enable_ADC_BIAS();
		if(chargeDect<10)
			chargeDect++;
		else
		{
			HID_Set_LED(LED_Pair,LED_OFF,0);
			HID_Set_LED(LED_Power,LED_OFF,0);
			HID_Set_LED(LED_CHARGE,LED_FLASH,0x7fff);
			RDA_WRITE_REG(0x40240014,0);
			RDA_WRITE_REG(0x40250100,1);
			while(1);
		}
	}
#if 0
	if(ghid.state == HidConnected){
			rssi = device_links[1].rssi_average;
			if(rssi < hid_config_eeprom.sleepTime) 
				HID_GPIO_write(SIG_GPIO,1);
			else
				HID_GPIO_write(SIG_GPIO,0);
			HID_GPIO_write(CONNECT_GPIO,1);
	}
	else{
		HID_GPIO_write(CONNECT_GPIO,0);
	}
#endif
	
	if(hid_config_eeprom.testDebug & HID_DEBUG_RSSI){
		
		if(ghid.state == HidConnected){
			testD[0] = 0x22;
			testD[1] = device_links[1].rssi_average;
			HID_Send_UART(testD,2);
			
		}
	}
	
}

void p_hid_connected(u_int16 handle)
{
	gHidHandle = handle;
	 HID_Set_LED(LED_Pair,LED_OFF,0);
	  HID_Set_LED(LED_Power,LED_OFF,0);

	gLinkIndex = 0x00;
	// move to the lmp_link_key_db.c
	LMkeydb_EE_Save_Addr();
	
}

 
